#ifndef _REGISTER_H_
#define _REGISTER_H_

#include "types.h"
#include "utils.h"

enum csr_addr {
    MSTATUS = 0x300,
    MIE = 0x304,
    MTVEC = 0x305,
    MEPC = 0x341,
    MCAUSE = 0x342,
    MIP = 0x344,
};

struct mstatus_t {
    uint32_t WPRI_0 : 1;
    uint32_t SIE    : 1;
    uint32_t WPRI_1 : 1;
    uint32_t MIE    : 1;
    uint32_t WPRI_2 : 1;
    uint32_t SPIE   : 1;
    uint32_t UBE    : 1;
    uint32_t MPIE   : 1;
    uint32_t SPP    : 1;
    uint32_t VS     : 2;
    uint32_t MPP    : 2;
    uint32_t FS	    : 2;
    uint32_t XS     : 2;
    uint32_t MPRV   : 1;
    uint32_t SUM    : 1;
    uint32_t MXR    : 1;
    uint32_t TVM    : 1;
    uint32_t TW     : 1;
    uint32_t TSR    : 1;
#ifdef CONFIG_ISA64
    uint16_t WPRI_3 : 9;
    uint32_t UXL    : 2;
    uint32_t SXL    : 2;
    uint32_t SBE    : 1;
    uint32_t MBE    : 1;
    uint64_t WPRI_4 : 25;
    uint32_t SD     : 1;
#else
    uint32_t WPRI_3 : 8;
    uint32_t SD     : 1;
#endif
};

static_assert(sizeof(mstatus_t) == 8, "mstatus_t");

struct mip_t {
    uint64_t blank_0 : 1;
    uint64_t SSIP    : 1;
    uint64_t blank_1 : 1;
    uint64_t MSIP    : 1;
    uint64_t blank_2 : 1;
    uint64_t STIP    : 1;
    uint64_t blank_3 : 1;
    uint64_t MTIP    : 1;
    uint64_t blank_4 : 1;
    uint64_t SEIP    : 1;
    uint64_t blank_5 : 1;
    uint64_t MEIP    : 1;
    uint64_t blank_6 : XLEN - 12;
};

static_assert(sizeof(mip_t) == 8, "mip_t");

struct mie_t {
    uint64_t blank_0 : 1;
    uint64_t SSIE    : 1;
    uint64_t blank_1 : 1;
    uint64_t MSIE    : 1;
    uint64_t blank_2 : 1;
    uint64_t STIE    : 1;
    uint64_t blank_3 : 1;
    uint64_t MTIE    : 1;
    uint64_t blank_4 : 1;
    uint64_t SEIE    : 1;
    uint64_t blank_5 : 1;
    uint64_t MEIE    : 1;
    uint64_t blank_6 : XLEN - 12;
};

static_assert(sizeof(mie_t) == 8, "mie_t");

#endif
